package imageEditor.utility;

import java.awt.Color;
import java.io.Serializable;



public class Shape implements Serializable{
	
	public enum shapeType{
		rectangle,
		ellipse;
	}
	
	private static final double DELTA = 5;
	private int[] dim;
	private shapeType type;
	private Color color;
	private String message;
	private boolean deleted;
	

	public Shape(int x, int y, int w, int h, shapeType t, Color c, String m){
		dim =new int[4];
		
		type=t;
		
		dim[0]=x;
		dim[1]=y;
		dim[2]=w;
		dim[3]=h;
		
		color=c;
		message=m;
		deleted=false;
	}
	
	public boolean isDeleted(){
		return deleted;
	}

	public Shape(double x, double y, double w, double h, shapeType t,Color c, String m) {
		this((int)x,(int)y,(int)w,(int)h,t,c,m);
	}

	public Shape(Point2d p, int w, int h, shapeType t,Color c, String m) {
		this(p.getX(),p.getY(),w,h,t,c,m);
	}

	public boolean contains(Point2d p) {
		
		switch(type){
			case rectangle: return rectCont(p.getX(),p.getY());
			case ellipse: return elipseCont(p.getX(),p.getY());
		}

		return false;
	}

	public boolean contains(double x, double y) {
		return contains(new Point2d((int)x, (int)y));
	}
	
	public boolean isInside(double x, double y){		
		double tmpX=dim[0]+DELTA;
		double tmpY=dim[1]+DELTA;
		
		double tmpW=dim[2]-2*DELTA;
		double tmpH=dim[3]-2*DELTA;
		
		Shape tmp=new Shape(tmpX,tmpY,tmpW,tmpH, type,Color.BLACK,"");
				
		return tmp.contains(x,y);
	}
	
	public String getMessage(){
		return message==null?"":message;
	}

	public int getCenterX() {
		return dim[0]+dim[3]/2;
	}


	public int getCenterY() {
		return dim[1]+dim[2]/2;
	}


	public shapeType getType() {
		return type;
	}

	public int getHeight() {
		return dim[3];
	}

	public int getWidth() {
		return dim[2];
	}


	public int getY() {
		return dim[1];
	}

	public int getX() {
		return dim[0];
	}

	public void resize(int x, int y) {
		dim[3]=Math.abs(dim[0]-x);
		dim[2]=Math.abs(dim[1]-y);
	}


	public void move(int x, int y) {
		dim[0]=x;
		dim[1]=y;
	}


	public void scale(double scale) {
		dim[3]*=scale;
		dim[2]*=scale;
		dim[0]*=scale;
		dim[1]*=scale;
		
	}


	private boolean rectCont(double x, double y){
		boolean h1=x<=dim[0]+dim[3];
		boolean h2=x>=dim[0];
		boolean h=h1&&h2;
		
		boolean w1=y<=dim[1]+dim[2];
		boolean w2=y>=dim[1];
		boolean w=w1&&w2;
		
		return w&&h;
	}

	private boolean elipseCont(double x, double y){
		boolean h1=x<=dim[0]+dim[3];
		boolean h2=x>=dim[0];
		boolean h=h1&&h2;
		
		if(h){
			
			double a2=dim[3]*dim[3]*1.0/4.0;
			double b2=dim[2]*dim[2]*1.0/4.0;
			
			double maxY1=-Math.sqrt((a2*b2-b2*(x-getCenterX())*(x-getCenterX()))/a2)+getCenterY();
			double maxY2=Math.sqrt((a2*b2-b2*(x-getCenterX())*(x-getCenterX()))/a2)+getCenterY();
			
			boolean w1=y<=maxY2;
			boolean w2=y>=maxY1;
			
			return w1&&w2;
		}
		
		return false;
	}
	
	public Color getColor(){
		return color;
	}

	public boolean isInside(Point2d p) {
		return isInside(p.getX(), p.getY());
	}

	public boolean isOnBorder(Point2d p) {
		return contains(p) && !isInside(p);
	}

	public void resize(Point2d end) {
		resize(end.getX(), end.getY());
	}

	public void move(Point2d p) {
		this.move(p.getX(),p.getY());
	}

	public Point2d getPosition() {
		return new Point2d(dim[0], dim[1]);
	}

	public int getBottomX() {
		return getX()+getHeight();
	}
	
	public int getBottomY() {
		return getY()+getWidth();
	}

	public boolean isOnRemove(Point2d p) {
		int x=p.getX();
		int y=p.getY();
		
		boolean h1=x<=dim[0]+10;
		boolean h2=x>=dim[0];
		boolean h=h1&&h2;
		
		boolean w1=y<=dim[1]+10;
		boolean w2=y>=dim[1];
		boolean w=w1&&w2;
		
		return w&&h;
	}

	public void delete() {
		deleted=true;
	}
}
